import { useImperativeHandle, useRef, useState, forwardRef } from "react";
/**
 * 父组件不能像vue那样直接操作子组件，需要通过ref来操作子组件暴露的方法，vue3的defineExpose也可以实现类似的功能
 * 
 * ref: 父组件传递的ref对象
   createHandle: 返回值，返回一个对象，对象的属性就是子组件暴露给父组件的方法或属性
   deps?:[可选] 依赖项，当依赖项发生变化时，会重新调用createHandle函数，类似于useEffect的依赖项
 
 * useImperativeHandle: 自定义暴露给父组件的实例值，v18配合forwardRef使用
   v19之后，forwardRef废弃了
 */

// v18写法，props和ref分开
interface ChildProps {
  name: string;
  count: number;
  addCount: () => void;
  subCount: () => void;
}
const Child = forwardRef<ChildProps>((props, ref) => {
  console.log("Child render", props);
  const [count, setCount] = useState(0);

  // 暴露给父组件的方法或属性
  useImperativeHandle(ref, () => {
    return {
      name: "child",
      count,
      addCount: () => setCount(count + 1),
      subCount: () => setCount(count - 1),
    };
  });

  return (
    <div>
      <p>子组件</p>
      <p>count: {count}</p>
      <button onClick={() => setCount(count + 1)}>子组件操作</button>
    </div>
  );
});

export function UseImperativeHandleDemo2() {
  // 这里也要指定类型
  const childRef = useRef<ChildProps>(null);

  const addCount = () => {
    const child = childRef.current;
    if (child) {
      child.addCount();
    }
  };

  const subCount = () => {
    const child = childRef.current;
    if (child) {
      child.subCount();
    }
  };

  return (
    <div>
      <h3>父组件操作子组件学习（v18)</h3>
      <button onClick={addCount}>父组件增加</button>
      <button onClick={subCount}>父组件减少</button>
      <Child ref={childRef} />
    </div>
  );
}
